package main

import "testing"

type identifier interface {
	idInLine() int32
	idNoInLine() int32
}

type id32 struct {
	id int32
}

func (id *id32) idInLine() int32 {
	return id.id
}

func (id *id32) idNoInLine() int32 {
	return id.id
}

var escapeMePlease *id32

//主要作用是强制变量存在heap上分配
//go:noinline
func escapeToHeap(id *id32) identifier {
	escapeMePlease = id
	return escapeMePlease
}

//直接调用
func BenchmarkMethodCall_direct(b *testing.B) {
	var myID int32
	b.Run("single/noinline", func(b *testing.B) {
		m := escapeToHeap(&id32{id: 6754}).(*id32)
		b.ResetTimer()
		for i := 0; i < b.N; i++ {
			myID = m.idNoInLine()
		}
	})
	b.Run("single/inline", func(b *testing.B) {
		m := escapeToHeap(&id32{id: 6754}).(*id32)
		b.ResetTimer()
		for i := 0; i < b.N; i++ {
			myID = m.idInLine()
		}
	})
}

func BenchmarkMethodCall_interface(b *testing.B) {
	var myID int32
	b.Run("single/noinline", func(b *testing.B) {
		m := escapeToHeap(&id32{id: 6754})
		b.ResetTimer()
		for i := 0; i < b.N; i++ {
			myID = m.idNoInLine()
		}
	})
	b.Run("single/inline", func(b *testing.B) {
		m := escapeToHeap(&id32{id: 6754})
		b.ResetTimer()
		for i := 0; i < b.N; i++ {
			myID = m.idInLine()
		}
	})
}
func main() {
}
